import Singleton from "../Base/Singleton";
import { ApiMsgEnum } from "../Common";
import { PlayerManager } from "./PlayerManager";
import { Room } from "./Room";


export class RoomManager extends Singleton {
    static get Instance() {
        return super.GetInstance<RoomManager>();
    }

    nextRoomId: number = 1;
    rooms: Set<Room> = new Set();
    idMapRooms: Map<number, Room> = new Map();
    createRoom(masterId: number) {
        const room = new Room(this.nextRoomId++, masterId);
        this.rooms.add(room);
        this.idMapRooms.set(room.rid, room);
        return room;
    }

    joinRoom(rid: number, uid: number) {
        const room = this.idMapRooms.get(rid)
        if (room) {
            room.join(uid);
            return room
        }
    }

    leaveRoom(rid: number, uid: number) {
        const room = this.idMapRooms.get(rid);
        if (room) {
            room.leave(uid)
            if (!room.players.size) {
                this.closeRoom(rid)
            }
        }
    }

    closeRoom(rid: number) {
        const room = this.idMapRooms.get(rid);
        if (room) {
            room.close()
            this.rooms.delete(room)
            this.idMapRooms.delete(rid)
        }
    }

    startRoom(rid: number, playerId: number) {
        const room = this.idMapRooms.get(rid)
        if (room && room.masterId === playerId) {
            room.start()
            return true;
        }
        return false;
    }

    syncRooms() {
        for (const player of PlayerManager.Instance.players) {
            player.connection.sendMsg(ApiMsgEnum.MsgRoomList, {
                list: this.getRoomsView()
            })
        }
    }

    syncRoom(rid: number) {
        const room = this.idMapRooms.get(rid)
        if (room) {
            room.sync()
        }
    }

    getRoomsView(rooms: Set<Room> = this.rooms) {
        return [...rooms].map(p => this.getRoomView(p))
    }

    getRoomView({ rid, masterId, players }: Room) {
        return {
            rid,
            masterId,
            players: PlayerManager.Instance.getPlayersView(players),
        }
    }
}
